package com.beaven.imclient.presenter.group;

import com.beaven.imclient.R;
import com.beaven.imclient.data.UserSelected;
import com.beaven.model.data.helper.GroupHelper;
import com.beaven.model.data.helper.UserHelper;
import com.beaven.model.model.api.RspModel;
import com.beaven.model.model.api.group.GroupMemberCreateModel;
import com.beaven.model.model.card.GroupMemberCard;
import com.beaven.model.model.db.User;
import com.beaven.model.model.db.User_Table;
import com.beaven.model.model.sp.Account;
import com.raizlabs.android.dbflow.sql.language.SQLite;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import rx.Subscriber;
import rx.functions.Func1;
import rx.subscriptions.CompositeSubscription;

/**
 * author: Beaven
 * time: 2017/6/2 15:04
 */

public class MemberPresenter implements MemberContract.Presenter {

  private MemberContract.View view;
  private String groupId;
  private boolean isAdd;
  private CompositeSubscription subscription;

  public MemberPresenter(MemberContract.View view, String groupId, boolean isAdd) {
    this.view = view;
    this.groupId = groupId;
    this.isAdd = isAdd;
    subscription = new CompositeSubscription();
  }

  @Override public void subscribe() {
    loadMember();
  }

  @Override public void unSubscribe() {
    view.hideLoading();
    subscription.clear();
  }

  @Override public void memberManager(List<String> memberList) {
    if (memberList == null || memberList.size() == 0) {
      return;
    }
    if (isAdd) {
      addMember(memberList);
    } else {
      deleteMember(memberList);
    }
  }

  private void loadLocalUser(List<UserSelected> userSelecteds) {
    List<User> userList = SQLite.select()
        .from(User.class)
        .where(User_Table.isFollow.eq(true))
        .and(User_Table.id.notEq(Account.getUserId()))
        .queryList();
    Map<String, UserSelected> selectedMap = new HashMap<>();
    for (UserSelected user : userSelecteds) {
      selectedMap.put(user.getUser().getId(), user);
    }
    List<UserSelected> selected = new ArrayList<>();
    for (User user : userList) {
      if (selectedMap.get(user.getId()) == null) {
        selected.add(UserSelected.build(user));
      }
    }
    view.showList(selected);
  }

  private void loadMember() {
    view.showLoading();
    subscription.add(GroupHelper.getGroupMember(groupId)
        .map(new Func1<RspModel<List<GroupMemberCard>>, List<UserSelected>>() {
          @Override public List<UserSelected> call(RspModel<List<GroupMemberCard>> listRspModel) {
            List<UserSelected> userList = new ArrayList<>();
            if (listRspModel.isSuccess()) {
              List<GroupMemberCard> memberCardList = listRspModel.getResult();
              for (GroupMemberCard card : memberCardList) {
                User user = UserHelper.findById(card.getUserId());
                if (!user.getId().equals(Account.getUserId())) {
                  userList.add(UserSelected.build(user));
                }
              }
            }
            return userList;
          }
        })
        .subscribe(new Subscriber<List<UserSelected>>() {
          @Override public void onCompleted() {

          }

          @Override public void onError(Throwable e) {
            view.showText(R.string.data_network_error);
            view.hideLoading();
          }

          @Override public void onNext(List<UserSelected> userSelecteds) {
            if (isAdd) {
              loadLocalUser(userSelecteds);
            } else {
              view.showList(userSelecteds);
            }
            view.hideLoading();
          }
        }));
  }

  private void addMember(List<String> userId) {
    List<GroupMemberCreateModel> models = new ArrayList<>();
    for (String id : userId) {
      models.add(new GroupMemberCreateModel(groupId, id));
    }
    view.showLoading();
    subscription.add(
        GroupHelper.addMember(models).subscribe(new Subscriber<RspModel<List<GroupMemberCard>>>() {
          @Override public void onCompleted() {

          }

          @Override public void onError(Throwable e) {
            view.hideLoading();
            view.showText(R.string.data_network_error);
          }

          @Override public void onNext(RspModel<List<GroupMemberCard>> listRspModel) {
            if (listRspModel.isSuccess()) {
              view.showText(R.string.load_success);
              view.finish();
            } else {
              view.showText(R.string.add_fail);
            }
            view.hideLoading();
          }
        }));
  }

  private void deleteMember(List<String> userId) {
    List<GroupMemberCreateModel> models = new ArrayList<>();
    for (String id : userId) {
      models.add(new GroupMemberCreateModel(groupId, id));
    }
    view.showLoading();
    subscription.add(GroupHelper.deleteMember(models)
        .map(new Func1<RspModel<List<GroupMemberCard>>, List<UserSelected>>() {
          @Override public List<UserSelected> call(RspModel<List<GroupMemberCard>> listRspModel) {
            List<UserSelected> userList = new ArrayList<>();
            if (listRspModel.isSuccess()) {
              List<GroupMemberCard> memberCardList = listRspModel.getResult();
              for (GroupMemberCard card : memberCardList) {
                User user = UserHelper.findById(card.getUserId());
                if (!user.getId().equals(Account.getUserId())) {
                  userList.add(UserSelected.build(user));
                }
              }
            } else {
              view.showText(R.string.load_error);
            }
            return userList;
          }
        })
        .subscribe(new Subscriber<List<UserSelected>>() {
          @Override public void onCompleted() {

          }

          @Override public void onError(Throwable e) {
            view.hideLoading();
            view.showText(R.string.data_network_error);
          }

          @Override public void onNext(List<UserSelected> userSelectedList) {
            view.clearList();
            view.showList(userSelectedList);
            view.hideLoading();
          }
        }));
  }
}
